/**
 * 私信API库
 * @author HalRui
 * @version 1.0.0
 * @description 提供私信相关的业务逻辑功能，包括消息发送、会话管理、消息查询、已读状态管理等操作
 * @date 2025年9月27日
 */

const Messages = require('../models/messages-model');
const UserInfos = require('../models/userinfos-model');
const { connectDB } = require('../utils/db');

/**
 * 发送私信
 * @param {Object} messageData - 私信数据
 * @param {number} messageData.senderId - 发送者ID
 * @param {number} messageData.receiverId - 接收者ID
 * @param {string} messageData.content - 消息内容
 * @param {string} [messageData.messageType='text'] - 消息类型
 * @param {Array} [messageData.attachments=[]] - 附件列表
 * @param {string} [messageData.ip=''] - IP地址
 * @returns {Promise<Object>} 发送的私信信息
 */
async function sendMessage(messageData) {
    try {
        await connectDB();
        
        const { senderId, receiverId, content, messageType = 'text', attachments = [], ip = '' } = messageData;
        
        // 验证必要参数
        if (!senderId || !receiverId || !content) {
            throw new Error('发送者ID、接收者ID和消息内容不能为空');
        }
        
        if (senderId === receiverId) {
            throw new Error('不能给自己发送私信');
        }
        
        // 验证用户是否存在
        const [sender, receiver] = await Promise.all([
            UserInfos.findOne({ userId: senderId, isDeleted: false }),
            UserInfos.findOne({ userId: receiverId, isDeleted: false })
        ]);
        
        if (!sender) {
            throw new Error('发送者不存在');
        }
        
        if (!receiver) {
            throw new Error('接收者不存在');
        }
        
        // 发送私信
        const message = await Messages.sendMessage({
            senderId,
            receiverId,
            content: content.trim(),
            messageType,
            attachments,
            ip
        });
        
        // 获取完整的消息信息
        const messageDetail = await getMessageDetail(message.messageId, senderId);
        
        return messageDetail;
    } catch (error) {
        console.error('发送私信失败:', error);
        throw error;
    }
}

/**
 * 获取会话列表
 * @param {Object} options - 查询选项
 * @param {number} options.userId - 用户ID
 * @param {number} [options.page=1] - 页码
 * @param {number} [options.limit=20] - 每页数量
 * @returns {Promise<Object>} 会话列表和分页信息
 */
async function getConversations(options) {
    try {
        await connectDB();
        
        const { userId, page = 1, limit = 20 } = options;
        
        if (!userId) {
            throw new Error('用户ID不能为空');
        }
        
        // 获取会话列表
        const result = await Messages.getConversations({
            userId,
            page,
            limit
        });
        
        // 获取对话用户信息
        const userIds = result.conversations.map(conv => {
            const lastMessage = conv.lastMessage;
            return lastMessage.senderId === userId ? lastMessage.receiverId : lastMessage.senderId;
        });
        
        const users = await UserInfos.find({ 
            userId: { $in: userIds }, 
            isDeleted: false 
        }).lean();
        
        const userMap = {};
        users.forEach(user => {
            userMap[user.userId] = {
                userId: user.userId,
                username: user.username,
                nickname: user.nickname,
                avatar: user.avatar
            };
        });
        
        // 组合会话和用户信息
        const conversationsWithUserInfo = result.conversations.map(conv => {
            const lastMessage = conv.lastMessage;
            const otherUserId = lastMessage.senderId === userId ? lastMessage.receiverId : lastMessage.senderId;
            const otherUser = userMap[otherUserId];
            
            return {
                conversationId: conv.conversationId,
                otherUser,
                lastMessage: {
                    messageId: lastMessage.messageId,
                    senderId: lastMessage.senderId,
                    receiverId: lastMessage.receiverId,
                    content: lastMessage.content,
                    messageType: lastMessage.messageType,
                    createAt: lastMessage.createAt
                },
                unreadCount: conv.unreadCount
            };
        }).filter(conv => conv.otherUser); // 过滤掉用户不存在的会话
        
        return {
            conversations: conversationsWithUserInfo,
            pagination: result.pagination
        };
    } catch (error) {
        console.error('获取会话列表失败:', error);
        throw error;
    }
}

/**
 * 获取会话消息列表
 * @param {Object} options - 查询选项
 * @param {string} options.conversationId - 会话ID
 * @param {number} options.userId - 用户ID
 * @param {number} [options.page=1] - 页码
 * @param {number} [options.limit=20] - 每页数量
 * @returns {Promise<Object>} 消息列表和分页信息
 */
async function getConversationMessages(options) {
    try {
        await connectDB();
        
        const { conversationId, userId, page = 1, limit = 20 } = options;
        
        if (!conversationId || !userId) {
            throw new Error('会话ID和用户ID不能为空');
        }
        
        // 验证用户是否参与此会话
        const [senderId, receiverId] = conversationId.split('_').map(id => parseInt(id));
        if (userId !== senderId && userId !== receiverId) {
            throw new Error('无权限访问此会话');
        }
        
        // 获取消息列表
        const result = await Messages.getConversationMessages({
            conversationId,
            userId,
            page,
            limit
        });
        
        // 获取发送者信息
        const senderIds = [...new Set(result.messages.map(msg => msg.senderId))];
        const users = await UserInfos.find({ 
            userId: { $in: senderIds }, 
            isDeleted: false 
        }).lean();
        
        const userMap = {};
        users.forEach(user => {
            userMap[user.userId] = {
                userId: user.userId,
                username: user.username,
                nickname: user.nickname,
                avatar: user.avatar
            };
        });
        
        // 组合消息和用户信息
        const messagesWithUserInfo = result.messages.map(msg => ({
            ...msg,
            sender: userMap[msg.senderId]
        }));
        
        return {
            messages: messagesWithUserInfo,
            pagination: result.pagination
        };
    } catch (error) {
        console.error('获取会话消息列表失败:', error);
        throw error;
    }
}

/**
 * 获取消息详情
 * @param {number} messageId - 消息ID
 * @param {number} userId - 用户ID
 * @returns {Promise<Object|null>} 消息详情
 */
async function getMessageDetail(messageId, userId) {
    try {
        await connectDB();
        
        if (!messageId || !userId) {
            throw new Error('消息ID和用户ID不能为空');
        }
        
        const message = await Messages.findOne({ 
            messageId, 
            isDeleted: false 
        }).lean();
        
        if (!message) {
            return null;
        }
        
        // 检查权限
        if (message.senderId !== userId && message.receiverId !== userId) {
            throw new Error('无权限访问此消息');
        }
        
        // 检查是否被用户删除
        if (message.deletedBy.some(record => record.userId === userId)) {
            return null;
        }
        
        // 获取发送者和接收者信息
        const [sender, receiver] = await Promise.all([
            UserInfos.findOne({ userId: message.senderId, isDeleted: false }).lean(),
            UserInfos.findOne({ userId: message.receiverId, isDeleted: false }).lean()
        ]);
        
        return {
            messageId: message.messageId,
            senderId: message.senderId,
            receiverId: message.receiverId,
            conversationId: message.conversationId,
            content: message.content,
            messageType: message.messageType,
            attachments: message.attachments,
            isRead: message.isRead,
            readAt: message.readAt,
            createAt: message.createAt,
            sender: sender ? {
                userId: sender.userId,
                username: sender.username,
                nickname: sender.nickname,
                avatar: sender.avatar
            } : null,
            receiver: receiver ? {
                userId: receiver.userId,
                username: receiver.username,
                nickname: receiver.nickname,
                avatar: receiver.avatar
            } : null
        };
    } catch (error) {
        console.error('获取消息详情失败:', error);
        throw error;
    }
}

/**
 * 标记消息为已读
 * @param {Object} options - 标记选项
 * @param {string} [options.conversationId] - 会话ID
 * @param {number} options.userId - 用户ID
 * @param {number[]} [options.messageIds] - 消息ID数组
 * @returns {Promise<Object>} 标记结果
 */
async function markAsRead(options) {
    try {
        await connectDB();
        
        const { conversationId, userId, messageIds } = options;
        
        if (!userId) {
            throw new Error('用户ID不能为空');
        }
        
        if (!conversationId && !messageIds) {
            throw new Error('会话ID或消息ID数组不能同时为空');
        }
        
        // 如果指定了会话ID，验证用户权限
        if (conversationId) {
            const [senderId, receiverId] = conversationId.split('_').map(id => parseInt(id));
            if (userId !== senderId && userId !== receiverId) {
                throw new Error('无权限访问此会话');
            }
        }
        
        const result = await Messages.markAsRead({
            conversationId,
            userId,
            messageIds
        });
        
        return result;
    } catch (error) {
        console.error('标记消息为已读失败:', error);
        throw error;
    }
}

/**
 * 删除消息
 * @param {number} messageId - 消息ID
 * @param {number} userId - 用户ID
 * @returns {Promise<Object>} 删除结果
 */
async function deleteMessage(messageId, userId) {
    try {
        await connectDB();
        
        if (!messageId || !userId) {
            throw new Error('消息ID和用户ID不能为空');
        }
        
        const result = await Messages.deleteMessage(messageId, userId);
        
        return result;
    } catch (error) {
        console.error('删除消息失败:', error);
        throw error;
    }
}

/**
 * 删除会话
 * @param {string} conversationId - 会话ID
 * @param {number} userId - 用户ID
 * @returns {Promise<Object>} 删除结果
 */
async function deleteConversation(conversationId, userId) {
    try {
        await connectDB();
        
        if (!conversationId || !userId) {
            throw new Error('会话ID和用户ID不能为空');
        }
        
        // 验证用户权限
        const [senderId, receiverId] = conversationId.split('_').map(id => parseInt(id));
        if (userId !== senderId && userId !== receiverId) {
            throw new Error('无权限删除此会话');
        }
        
        const result = await Messages.deleteConversation(conversationId, userId);
        
        return result;
    } catch (error) {
        console.error('删除会话失败:', error);
        throw error;
    }
}

/**
 * 获取未读消息数量
 * @param {number} userId - 用户ID
 * @returns {Promise<number>} 未读消息数量
 */
async function getUnreadCount(userId) {
    try {
        await connectDB();
        
        if (!userId) {
            throw new Error('用户ID不能为空');
        }
        
        const count = await Messages.getUnreadCount(userId);
        
        return count;
    } catch (error) {
        console.error('获取未读消息数量失败:', error);
        throw error;
    }
}

/**
 * 搜索消息
 * @param {Object} options - 搜索选项
 * @param {number} options.userId - 用户ID
 * @param {string} options.keyword - 搜索关键词
 * @param {number} [options.page=1] - 页码
 * @param {number} [options.limit=20] - 每页数量
 * @returns {Promise<Object>} 搜索结果
 */
async function searchMessages(options) {
    try {
        await connectDB();
        
        const { userId, keyword, page = 1, limit = 20 } = options;
        
        if (!userId || !keyword) {
            throw new Error('用户ID和搜索关键词不能为空');
        }
        
        // 搜索消息
        const result = await Messages.searchMessages({
            userId,
            keyword: keyword.trim(),
            page,
            limit
        });
        
        // 获取相关用户信息
        const userIds = [...new Set([
            ...result.messages.map(msg => msg.senderId),
            ...result.messages.map(msg => msg.receiverId)
        ])];
        
        const users = await UserInfos.find({ 
            userId: { $in: userIds }, 
            isDeleted: false 
        }).lean();
        
        const userMap = {};
        users.forEach(user => {
            userMap[user.userId] = {
                userId: user.userId,
                username: user.username,
                nickname: user.nickname,
                avatar: user.avatar
            };
        });
        
        // 组合消息和用户信息
        const messagesWithUserInfo = result.messages.map(msg => ({
            ...msg,
            sender: userMap[msg.senderId],
            receiver: userMap[msg.receiverId]
        }));
        
        return {
            messages: messagesWithUserInfo,
            pagination: result.pagination
        };
    } catch (error) {
        console.error('搜索消息失败:', error);
        throw error;
    }
}

/**
 * 获取消息统计
 * @param {number} userId - 用户ID
 * @returns {Promise<Object>} 消息统计信息
 */
async function getMessageStats(userId) {
    try {
        await connectDB();
        
        if (!userId) {
            throw new Error('用户ID不能为空');
        }
        
        const stats = await Messages.getMessageStats(userId);
        
        return stats;
    } catch (error) {
        console.error('获取消息统计失败:', error);
        throw error;
    }
}

/**
 * 生成会话ID
 * @param {number} userId1 - 用户1 ID
 * @param {number} userId2 - 用户2 ID
 * @returns {string} 会话ID
 */
function generateConversationId(userId1, userId2) {
    return userId1 < userId2 ? `${userId1}_${userId2}` : `${userId2}_${userId1}`;
}

/**
 * 解析会话ID
 * @param {string} conversationId - 会话ID
 * @returns {Object} 解析结果
 */
function parseConversationId(conversationId) {
    const [userId1, userId2] = conversationId.split('_').map(id => parseInt(id));
    return { userId1, userId2 };
}

module.exports = {
    sendMessage,
    getConversations,
    getConversationMessages,
    getMessageDetail,
    markAsRead,
    deleteMessage,
    deleteConversation,
    getUnreadCount,
    searchMessages,
    getMessageStats,
    generateConversationId,
    parseConversationId
};